/*
 * Copyright 2014-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
<template>
  <div class="send-wrapper">
    <div class="send-item">
      <span class="send-item-title">{{ this.$t('contracts.contractName') }}:</span>
      <span>{{ data.contractName }}</span>
    </div>
    <div class="send-item">
      <span class="send-item-title">CNS:</span>
      <span>
        <el-checkbox v-model="isCNS" @change="changeCns" />
      </span>
    </div>
    <div v-if="isCNS" class="send-item">
      <span class="send-item-title" />
      <el-input v-model.trim="cnsName" style="width: 260px;margin-bottom:4px;" :placeholder="$t('dialog.cnsName')">
        <template slot="prepend">
          <span class="">name</span>
        </template>
      </el-input>
    </div>
    <div v-if="isCNS" class="send-item">
      <span class="send-item-title" />
      <el-input v-model.trim="cnsVersion" style="width: 260px;margin-bottom:4px;" :placeholder="$t('dialog.cnsVersion')">
        <template slot="prepend">
          <span class="">version</span>
        </template>
      </el-input>
    </div>
    <div v-else class="send-item">
      <span class="send-item-title">{{ this.$t('contracts.contractAddress') }}:</span>
      <el-input v-model="contractAddress" style="width: 260px;" :placeholder="$t('contracts.contractAddressInput')" />
      <el-tooltip class="item" effect="dark" :content="$t('contracts.contractAddressInfo')" placement="top-start">
        <i class="el-icon-info" />
      </el-tooltip>
    </div>
    <div v-show="showUser" class="send-item">
      <span class="send-item-title">{{ this.$t('contracts.user') }}:</span>
      <el-select v-model="transation.userName" :placeholder="$t('contracts.selectUser')" style="width:260px">
        <el-option v-for="(item,index) in userList" :key="item.userId" :label="item.userName" :value="item.address">
          <span>{{ item.userName }}</span>
          <!-- <span class="font-12">{{splitString(item.address)}}...</span> -->
          <span class="font-12">{{ item.address }}</span>
        </el-option>
      </el-select>
      <span v-if="isUserNameShow" class="contract-code-done" @click="$store.dispatch('switch_creat_user_dialog')">
        <span target="_blank" style="cursor:pointer;text-decoration:underline;">{{ this.$t("privateKey.addUser") }}</span>
      </span>
    </div>
    <el-dialog :visible.sync="$store.state.creatUserVisible" :title="$t('privateKey.createUser')" width="640px" :append-to-body="true" class="dialog-wrapper" center>
      <v-creatUser ref="creatUser" :disable-pub="true" @creatUserClose="creatUserClose" />
    </el-dialog>
    <div class="send-item">
      <span class="send-item-title">{{ this.$t('contracts.method') }}:</span>
      <el-select v-model="transation.funcType" :placeholder="$t('contracts.methodType')" style="width:120px" @change="changeType($event)">
        <el-option label="function" :value="'function'" />
      </el-select>
      <el-select v-show="funcList.length > 0" v-model="transation.funcName" :placeholder="$t('contracts.methodName')" filterable style="width:135px" @change="changeFunc">
        <el-option v-for="item in funcList" :key="item.funcId" :label="item.name" :value="item.funcId" />
      </el-select>
    </div>
    <div v-show="pramasData.length" class="send-item" style="line-height: 25px;">
      <span class="send-item-title" style="position: relative;top: 5px;">{{ this.$t("contracts.params") }}:</span>
      <ul class="send-ul" style="position: relative;top: -25px;">
        <li v-for="(item,index) in pramasData" :key="index" style="margin-left:80px;margin-bottom: 5px;">
          <template v-if="item.type=='string'">
            <el-input v-model="transation.funcValue[index]" style="width: 260px;" :placeholder="item.type">
              <template slot="prepend">
                <span class="">{{ item.name }}</span>
              </template>
            </el-input>
          </template>
          <template v-else>
            <el-input v-model.trim="transation.funcValue[index]" style="width: 260px;" :placeholder="item.type">
              <template slot="prepend">
                <span class="">{{ item.name }}</span>
              </template>
            </el-input>
          </template>

        </li>
        <p style="padding: 5px 0 0 28px;"><i class="el-icon-info" style="padding-right: 4px;" />{{ this.$t("contracts.paramsInfo") }}</p>
      </ul>

    </div>
    <div class="text-right send-btn">
      <el-button @click="close">{{ this.$t("text.cancel") }}</el-button>
      <el-button type="primary" :disabled="buttonClick" @click="submit('transation')">{{ this.$t("text.sure") }}</el-button>
    </div>
  </div>
</template>
<script>
import { sendTransation, getUserList, findCnsInfo } from '@/api/exercises'
import errcode from '@/utils/errcode'
import { isJson } from '@/utils/util'
import creatUser from '@/views/privateKeyManagement/components/creatUser'

export default {
  name: 'SendTransation',
  components: {
    'v-creatUser': creatUser
  },
  props: ['data', 'dialogClose', 'abi', 'version', 'address'],
  data: function() {
    return {
      transation: {
        userName: '',
        funcName: '',
        funcValue: [],
        funcType: 'function',
        reqVal: []
      },
      userId: '',
      userList: [],
      abiList: [],
      pramasData: [],
      funcList: [],
      buttonClick: false,
      contractVersion: this.version,
      contractAddress: this.data.contractAddress || '',
      constant: false,
      pramasObj: null,
      stateMutability: '',
      isCNS: false,
      cnsList: [],
      cnsVersion: '',
      cnsName: '',
      isUserNameShow: false
    }
  },
  computed: {
    showUser() {
      let showUser = true
      if (this.constant || this.stateMutability === 'view' || this.stateMutability === 'pure') {
        showUser = false
      }
      return showUser
    }
  },
  mounted: function() {
    this.getUserData()
    this.formatAbi()
  },
  methods: {
    submit: function(formName) {
      if (this.isCNS) {
        if (!this.cnsName || !this.cnsVersion) {
          this.$messageOnce({
            type: 'error',
            message: this.$t('text.cnsNameVersion')
          })
          return
        } else {
          this.send()
        }
      } else {
        this.send()
      }
    },
    close: function(formName) {
      this.$emit('close', false)
    },
    changeType: function(val) {
      this.funcList = []
      if (val && val === 'function') {
        this.abiList.forEach((value, index) => {
          if (value.type === val) {
            value.funcId = index
            this.funcList.push(value)
          }
        })
      } else if (val && val === 'constructor') {
        this.abiList.forEach(value => {
          if (value.type === val) {
            this.pramasData = value.inputs
            this.pramasObj = value
          }
        })
      } else {
        this.abiList.forEach((value, index) => {
          if (value.type === 'function') {
            value.funcId = index
            this.funcList.push(value)
          }
        })
      }
      if (this.funcList.length) {
        this.transation.funcName = this.funcList[0].funcId
      }
    },
    formatAbi: function() {
      const abi = this.abi
      if (abi) {
        this.abiList = JSON.parse(abi)
        this.changeType()
      }
    },
    changeFunc: function() {
      this.constant = false
      this.funcList.forEach(value => {
        if (value.funcId === this.transation.funcName) {
          this.pramasData = value.inputs
          this.constant = value.constant
          this.pramasObj = value
          this.stateMutability = value.stateMutability
        }
      })
      this.funcList.sort(function(a, b) {
        return (a.name + '').localeCompare(b.name + '')
      })
    },
    getUserData: function() {
      const reqData = {
        groupId: 1,
        pageNumber: 1,
        pageSize: 1000
      }
      const query = {}

      // TODO 角色
      if (localStorage.getItem('root') === 'developer') {
        query.account = localStorage.getItem('user')
      }
      getUserList(reqData, query)
        .then(res => {
          if (res.code === 0) {
            if (res.data.length == 0) {
              this.$messageOnce({
                type: 'info',
                message: this.$t('contracts.addPrivateKeyInfo')
              })
            }
            res.data.forEach(value => {
              if (value.hasPk === 1) {
                this.userList.push(value)
              }
            })
            if (this.userList.length) {
              this.transation.userName = this.userList[0].address
              this.isUserNameShow = false
            } else {
              this.isUserNameShow = true
              this.placeholderText = this.$t('placeholder.selectedNoUser')
            }
            this.changeFunc()
          } else {
            this.$messageOnce({
              message: this.$chooseLang(res.code),
              type: 'error',
              duration: 2000
            })
          }
        })
        .catch(err => {
          this.$messageOnce({
            message: err.data || this.$t('text.systemError'),
            type: 'error',
            duration: 2000
          })
        })
    },
    send: function() {
      this.buttonClick = true
      const pattren = /^\s+|\s+$/g
      if (this.transation.funcType === 'constructor') {
        this.transation.funcName = this.data.contractName
      }

      if (this.transation.funcValue.length) {
        for (let i = 0; i < this.transation.funcValue.length; i++) {
          const data = this.transation.funcValue[i].replace(
            /^\s+|\s+$/g,
            ''
          )
          if (data && isJson(data)) {
            try {
              this.transation.reqVal[i] = JSON.parse(data)
            } catch (error) {
              console.log(error)
            }
          } else if (data === 'true' || data === 'false') {
            this.transation.reqVal[i] = eval(data.toLowerCase())
          } else {
            this.transation.reqVal[i] = data
          }
        }
      }
      let functionName = ''
      this.funcList.forEach(value => {
        if (value.funcId == this.transation.funcName) {
          functionName = value.name
        }
      })

      const data = {
        groupId: 1,
        user: this.constant || this.stateMutability === 'view' || this.stateMutability === 'pure' ? '' : this.transation.userName,
        contractName: this.data.contractName,
        funcName: functionName || '',
        funcParam: this.transation.reqVal,
        contractId: this.data.contractId,
        contractAbi: [this.pramasObj],
        useCns: this.isCNS,
        cnsName: this.isCNS ? this.cnsName : '',
        version: this.isCNS ? this.cnsVersion : ''

      }
      if (this.contractAddress) {
        data.contractAddress = this.contractAddress
      }
      sendTransation(data)
        .then(res => {
          this.buttonClick = false
          this.close()
          if (res.code === 0) {
            var resData = res.data
            const successData = {
              resData: resData,
              input: {
                name: functionName,
                inputs: this.pramasData
              },
              data: this.pramasObj
            }
            if (this.contractAddress && !this.data.contractAddress) {
              successData.contractAddress = this.contractAddress
            }
            this.$emit('success', Object.assign({}, successData, {
              constant: this.constant
            }))
            if (this.constant || this.stateMutability === 'view' || this.stateMutability === 'pure') {
              this.$messageOnce({
                type: 'success',
                message: this.$t('text.selectSuccess')
              })
            } else {
              if (resData.status == '0x0') {
                this.$messageOnce({
                  type: 'success',
                  message: this.$t('text.transactionSuccess')
                })
              } else {
                this.$messageOnce({
                  type: 'success',
                  message: this.$t('text.transactionFail')
                })
              }
            }
          } else {
            this.$messageOnce({
              message: this.$chooseLang(res.code),
              type: 'error',
              duration: 2000
            })
            this.close()
          }
        })
        .catch(err => {
          this.buttonClick = false
          this.close()
          this.$messageOnce({
            message: err.data || this.$t('text.systemError'),
            type: 'error',
            duration: 2000
          })
        })
    },
    splitString(val) {
      var str = val
      return str.substring(0, 8)
    },
    changeCns(val) {
      if (val) {
        this.queryFindCnsInfo()
      }
    },
    queryFindCnsInfo() {
      const param = {
        groupId: 1,
        contractAddress: this.data.contractAddress
      }
      findCnsInfo(param)
        .then(res => {
          if (res.code === 0) {
            if (res.data) {
              this.cnsVersion = res.data.version
              this.cnsName = res.data.cnsName
            }
          } else {
            this.$messageOnce({
              type: 'error',
              message: this.$chooseLang(res.code)
            })
          }
        })
    },
    creatUserClose() {
      this.getUserData()
    }
  }
}
</script>

<style scoped>
/* * {
  margin: 0;
  padding: 0;
} */
.send-wrapper {
}
.send-item {
  line-height: 30px;
  margin-bottom: 24px;
}
.send-item-title {
  display: inline-block;
  width: 60px;
  text-align: right;
  margin-right: 20px;
}
.send-item-params {
  display: inline-block;
}
.send-item >>> .el-input__inner {
  height: 32px;
  line-height: 32px;
}
.send-body {
  overflow-y: scroll;
  max-height: 400px;
  min-height: 200px;
}
.send-btn {
  margin-bottom: 24px;
  margin-top: 24px;
}
.send-btn >>> .el-button {
  padding: 9px 16px;
}
.send-item >>> .el-form-item__error {
  left: 180px !important;
}
.send-item >>> .el-input-group__prepend {
  width: 60px;
}
.send-item >>> .el-form-item {
  line-height: 30px;
  margin-bottom: 24px;
}

.send-ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

</style>
